package com.liuya.safe.entitle.controller;

import com.liuya.common.SpringUtils;
import com.liuya.common.WebUtil;
import com.liuya.safe.util.Constants;
import com.liuya.safe.entitle.handler.DecisionEntitlementHandler;
import com.liuya.safe.entitle.service.EntitleManagerService;
import com.liuya.safe.entitle.service.PrivilegeManagerService;
import com.liuya.safe.model.SafePrivilege;
import com.liuya.safe.model.SafeUser;
import com.liuya.safe.policy.controller.AbstractTestController;
import com.liuya.safe.policy.service.QueryManagerService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.liuya.entitle.DecisionEntitlementTestResult;

/**
 * 权限管理
 * @author liuya
 * @date 20160826
 */
@Controller
@Api(value = "权限管理", description = "权限管理")
@RequestMapping(value = "decisionEntitlementTest")
public class DecisionEntitlementTestContrller extends AbstractTestController {
    private static final Log log = LogFactory.getLog(DecisionEntitlementTestContrller.class);

    @ApiOperation(value = "跳转到主页")
//    @RequiresPermissions("sys.nonRolePriviMng.decision")
    @RequestMapping(value = "/decision")
    public Object decision(HttpServletRequest req, HttpServletResponse rep, ModelMap modelMap){
        DecisionEntitlementHandler handler = getHandler(req);
        modelMap.addAttribute("handler", handler);
        String oper = req.getParameter("oper");
        req.setAttribute("oper", oper);

        return "privilege/decisionEntitlementTest";
    }

    @ApiOperation(value = "查询会话")
//    @RequiresPermissions("sys.nonRolePriviMng.returns")
    @RequestMapping(value = "/returns")
    public Object returns(HttpServletRequest req, HttpServletResponse rep, ModelMap modelMap){
        DecisionEntitlementHandler handler = getHandler(req);
        String gotoUrl = "./nonRolePriviMng/openTree.do";
        if (handler.getPrivilege().getType() == 0) {
            gotoUrl = "./privilegeMng/openTree.do";
        }

        String key = getHandlerAttributeKey(req);
        req.getSession().removeAttribute(key);
        return "redirect:/" + gotoUrl;
    }

    @ApiOperation(value = "查询会话")
//    @RequiresPermissions("sys.nonRolePriviMng.runTest")
    @RequestMapping(value = "/runTest")
    public Object runTest(HttpServletRequest req, HttpServletResponse rep, ModelMap modelMap) throws IOException {
        String oper = req.getParameter("oper");
        DecisionEntitlementHandler handler = getHandler(req);
        modelMap.addAttribute("handler", handler);

        SafeUser testUser = buildTestUser(req, true);

        Map testCtx = null;
        Object testBdData = null;
        try {
            testCtx = buildTestContext(req, handler.getTestContextFields());
            testBdData = buildTestBusinessData(req, handler.getTestBusinessDataFields());
        } catch (Exception e) {
            log.error(e);
            PrintWriter writer = rep.getWriter();
            writer.write("<font color='red'><pre>");
            e.printStackTrace(writer);
            writer.write("</pre></font>");
        }

        DecisionEntitlementTestResult testResult;
        try {
            if (testCtx == null) {
                testCtx = new HashMap();
            }
            testCtx.put(Constants.BUSINESS_DATA, testBdData);
            testResult = handler.run(req.getLocale(), testUser, testCtx);
            req.setAttribute("testResult", testResult);

            return "privilege/testDecisionEntitlementResult";
        } catch (Exception e) {
            log.error("", e);
            PrintWriter writer = rep.getWriter();
            writer.write("<font color='red'><pre>");
            e.printStackTrace(writer);
            writer.write("</pre></font>");
        }
        return "";
    }

    @ApiOperation(value = "查询会话")
//    @RequiresPermissions("sys.nonRolePriviMng.setBusinessDataClass")
    @RequestMapping(value = "/setBusinessDataClass")
    public Object setBusinessDataClass(HttpServletRequest req, HttpServletResponse rep, ModelMap modelMap) throws IOException {

        DecisionEntitlementHandler handler = getHandler(req);
        modelMap.addAttribute("handler", handler);

        String bdClass = req.getParameter("businessDataClass");
        handler.setBusinessDataClass(bdClass);

        try {
            req.setAttribute("testBusinessDataFields", handler.getTestBusinessDataFields());
            req.setAttribute("testBusinessDataFieldTypes", handler.getTestBusinessDataFieldTypes());
        } catch (Exception e) {
            log.error("", e);
            PrintWriter writer = rep.getWriter();
            writer.write("<font color='red'><pre>");
            e.printStackTrace(writer);
            writer.write("</pre></font>");
        }
        req.setAttribute("bdClass", bdClass);

        return "common/inputTestBusinessData";
    }

    public DecisionEntitlementHandler createHandler(HttpServletRequest req) {
        String id = WebUtil.getStringParameter(req, "id", "-23");

        PrivilegeManagerService pvlgMng = (PrivilegeManagerService) SpringUtils.getBean("privilegeManagerService");
        EntitleManagerService entitleMng = (EntitleManagerService) SpringUtils.getBean("entitleManagerService");
        QueryManagerService queryMng = (QueryManagerService) SpringUtils.getBean("queryManagerService");

        SafePrivilege pvlg = pvlgMng.getPrivilege(id);
        Collection entitlements = entitleMng.getDecisionEntitlements(id);

        if (log.isDebugEnabled()) {
            log.debug("id=" + id + ", name=" + pvlg.getName());
        }

        return new DecisionEntitlementHandler(pvlg, entitlements);
    }

    public String getHandlerAttributeKey(HttpServletRequest req) {
        int id = WebUtil.getIntParameter(req, "id", 0);
        return "_$safeDecisionEntitlement_" + id;
    }

    private DecisionEntitlementHandler getHandler(HttpServletRequest req) {
        String oper = req.getParameter("oper");
        String key = getHandlerAttributeKey(req);
        DecisionEntitlementHandler handler = null;
        Object obj = req.getSession().getAttribute(key);

        if (obj == null || "loadFresh".equals(oper)) {
            handler = createHandler(req);

            // save into session, will be removed when policy is saved
            req.getSession().setAttribute(key, handler);
        } else {
            handler = (DecisionEntitlementHandler) obj;
        }

        return handler;
    }

}
